package org.ponly.cta4j.factory.gimpy;

import com.jhlabs.image.PinchFilter;
import com.jhlabs.math.ImageFunction2D;
import org.ponly.cta4j.CaptchaFactory;
import org.ponly.cta4j.drawing.FilterablePainter;
import org.ponly.cta4j.drawing.Painter;
import org.ponly.cta4j.drawing.background.BackgroundBrush;
import org.ponly.cta4j.drawing.background.ColorBackgroundBrush;
import org.ponly.cta4j.drawing.color.RandomColorGenerator;
import org.ponly.cta4j.drawing.filter.BufferedImageOpFilter;
import org.ponly.cta4j.drawing.filter.Filter;
import org.ponly.cta4j.drawing.font.FontFamily;
import org.ponly.cta4j.drawing.font.RandomFontFamily;
import org.ponly.cta4j.drawing.text.GlyphsBrush;
import org.ponly.cta4j.drawing.text.TextBrush;
import org.ponly.cta4j.drawing.text.glyphsvisitor.GlyphsVisitor;
import org.ponly.cta4j.drawing.text.glyphsvisitor.OverlapGlyphsUsingShapeVisitor;
import org.ponly.cta4j.drawing.text.glyphsvisitor.TranslateAllToRandomPointVisitor;
import org.ponly.cta4j.factory.ProxiedCaptchaFactory;

import java.awt.*;

/**
 * Gmail 风格的验证码工厂, 来源于网络 jcaptcha GMailEngine.
 *
 * @author vacoor
 * @since 1.0
 */
public class GmailFactory extends ProxiedCaptchaFactory {
    /**
     * 默认实例.
     */
    public static final GmailFactory INSTANCE = new GmailFactory();

    /**
     * gmail style captcha width.
     */
    private static final int GMAIL_WIDTH = 200;

    /**
     * gmail style captcha height.
     */
    private static final int GMAIL_HEIGHT = 70;

    private final GimpyFactory gmailFactory = createGmailFactory();

    /**
     * {@inheritDoc}
     */
    @Override
    protected CaptchaFactory getCaptchaFactory() {
        return gmailFactory;
    }

    /**
     * 创建一个 Gmail 风格的验证码工厂.
     *
     * @return 验证码工厂
     */
    protected GimpyFactory createGmailFactory() {
        // build a text filter.
        final PinchFilter pinch = new PinchFilter();
        pinch.setAmount(-.5f);
        pinch.setRadius(30);
        pinch.setAngle((float) (Math.PI / 16));
        pinch.setCentreX(0.5f);
        pinch.setCentreY(-0.01f);
        pinch.setEdgeAction(ImageFunction2D.CLAMP);

        final PinchFilter pinch2 = new PinchFilter();
        pinch2.setAmount(-.6f);
        pinch2.setRadius(70);
        pinch2.setAngle((float) (Math.PI / 16));
        pinch2.setCentreX(0.3f);
        pinch2.setCentreY(1.01f);
        pinch2.setEdgeAction(ImageFunction2D.CLAMP);

        final PinchFilter pinch3 = new PinchFilter();
        pinch3.setAmount(-.6f);
        pinch3.setRadius(70);
        pinch3.setAngle((float) (Math.PI / 16));
        pinch3.setCentreX(0.8f);
        pinch3.setCentreY(-0.01f);
        pinch3.setEdgeAction(ImageFunction2D.CLAMP);

        final Filter textFilter = BufferedImageOpFilter.create(pinch, pinch2, pinch3);
        final BackgroundBrush backgroundBrush = new ColorBackgroundBrush(Color.WHITE);
        final TextBrush textBrush = new GlyphsBrush(7, 7, new RandomColorGenerator(new Color[]{
                new Color(23, 170, 27),
                new Color(220, 34, 11),
                new Color(23, 67, 172)
        }), new GlyphsVisitor[]{
                new OverlapGlyphsUsingShapeVisitor(3),
                new TranslateAllToRandomPointVisitor()
        });

        final FontFamily fontFamily = new RandomFontFamily(50, 50, new Font[]{
                new Font("nyala", Font.BOLD, 50), //
                new Font("Bell MT", Font.PLAIN, 50), //
                new Font("Credit valley", Font.BOLD, 50) //
        }, false);

        //
        final Painter painter = new FilterablePainter(backgroundBrush, textBrush, fontFamily, textFilter);
        final TextGenerator textGenerator = new RandomTextGenerator();  // TODO load from todo list

        return new GimpyFactory(GMAIL_WIDTH, GMAIL_HEIGHT, painter, textGenerator, false);
    }
}
